﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Security;
using System.Web;
using VideoSeller.Business.Data;
using VideoSeller.Business.Data.Enums;
using VideoSeller.Core.Interfaces;

namespace VideoSeller.Business.Models
{
	public class ClientModel : Repository<Client>
	{
        public static readonly Guid anonimeGuid = new Guid("6FA38797-D0C0-474E-B226-1D6E193ADFB0");
		private readonly IDatabaseSettingsProvider _databaseSettingsProvider;
		private readonly MailModel _mailModel;
		private readonly TeamChatModel _teamChatModel;
		private readonly WaitModel _waitModel;
		private readonly MembershipUserModel _membershipUserModel;
		private readonly FinanceModel _financeModel;
		private readonly OnlineContentModel _onlineContentModel;
		private readonly OnlineRatingModel _onlineRatingModel;
		private readonly OnlineContentClaimModel _onlineContentClaimModel;
        private readonly SettingsModel _settingsModel;

		public ClientModel(MailModel mailModel, MembershipUserModel membershipUserModel, FinanceModel financeModel, IDatabaseSettingsProvider databaseSettingsProvider, OnlineContentModel onlineContentModel, OnlineRatingModel onlineRatingModel, OnlineContentClaimModel onlineContentClaimModel, TeamChatModel teamChatModel, WaitModel waitModel, SettingsModel settingsModel)
		{
			_mailModel = mailModel;
			_membershipUserModel = membershipUserModel;
			_financeModel = financeModel;
			_databaseSettingsProvider = databaseSettingsProvider;
			_onlineContentModel = onlineContentModel;
			_onlineRatingModel = onlineRatingModel;
			_onlineContentClaimModel = onlineContentClaimModel;
			_teamChatModel = teamChatModel;
			_waitModel = waitModel;
            _settingsModel = settingsModel;
		}

		public IEnumerable<Client> GetClients()
		{
			return Table.AsEnumerable();
		}
        public IEnumerable<Client> GetRatedM(int topNum)
        {
            return GetClients().OrderByDescending(m=>m.m_Rating).Take(topNum);
        }
        public IEnumerable<Client> GetRatedC(int topNum)
        {
            return GetClients().OrderByDescending(m => m.c_Rating).Take(topNum);
        }
        //  visell.tv%2Faccount%2Fconfirm%3Fu%3D5fa31a43-095f-404c-8f57-bb19283cb3ab&a%3D34e1a027-0e21-4720-b5a9-9da275647e64
		public Client GetClient(Guid id)
		{
			Client ret = Table.SingleOrDefault(x => x.UserId == id);
            return ret;

		}

		public bool IsPersonalInfoEmpty(Guid userId)
		{
			var user = GetClient(userId);

			if (user != null)
			{
				return string.IsNullOrEmpty(user.FirstName) || string.IsNullOrEmpty(user.LastName) ||
				       !user.Birthday.HasValue || !user.CountryId.HasValue || !user.Sex.HasValue ||
				       string.IsNullOrEmpty(user.Address);
			}

			return false;
		}

		public bool RegisterClient(string login, string password, string email, string fromGuid)
		{
			var membershipUser = Membership.CreateUser(login, password, email);
            //
			membershipUser.IsApproved = false; //DEBUG = default is false
            if (fromGuid != "")
                membershipUser.Comment = fromGuid;
            Membership.UpdateUser(membershipUser);
            //
			var user = _membershipUserModel.GetMembershipUser(login);
            
            var client = RegisterClientVisell(user, email);
			Roles.AddUserToRole(login, UserRole.User.ToString());

			var url = string.Format("{0}account/confirm?u={1}&a={2}", _databaseSettingsProvider.MainWebPath, user.UserId, client.ActivationCode);

			return _mailModel.SendRegistrationConfirmation(login, email, url);
		}
        public Client RegisterClientVisell(Data.MembershipUser user)
        {
            try
            {
                String email = Membership.GetUser(user.UserName).Email;
                return RegisterClientVisell(user, email);
            }
            catch
            {
                return null;
            }
        }
        public Client RegisterClientVisell(Data.MembershipUser user,  string email)
        {
                var client = new Client
                {
                    UserId = user.UserId,
                    Login = user.UserName,
                    Email = email,
                    FirstName = string.Empty,
                    LastName = string.Empty,
                    About = string.Empty,
                    Birthday = null,
                    HomeSiteUrl = string.Empty,
                    Sex = true,
                    ActivationCode = Guid.NewGuid(),
                    ShowToOther = string.Empty,
                    Culture= "en-US"
                };

                Insert(client);
                _financeModel.AddClientFinance(client);
            return  client;

        }
		public bool ApproveClient(Guid userId, Guid code)
		{
            String fromOther = "";
			var client = Table.SingleOrDefault(x => x.UserId == userId);

			if (client != null && client.ActivationCode == code)
			{
               
				var user = Membership.GetUser(client.Login);

				if (user != null)
				{
                    if (user.IsApproved == false && user.Comment != null && user.Comment != "")
                        fromOther = user.Comment;
                    user.Comment =""; //clear user id for bonus
					user.IsApproved = true;
					Membership.UpdateUser(user);
					FormsAuthentication.SetAuthCookie(user.UserName, true);
                    if (fromOther != "")
                    {
                        try
                        {  //check if comment=guid string
                            Guid g = new Guid();
                            if (Guid.TryParse(fromOther, out g))
                            {
                                AddBonusMany(client, g);
                            }
                        }
                        catch
                        {
                        }
                    }
					return true;
				}
			}

			return false;
		}
        public bool AddBonusMany(Client newClient, Guid uid)
        {
            decimal sumadd = 0;
            Setting s = _settingsModel.GetSetting("ActionManyAdd");

            try
            {
                if (s != null)
                    if (!decimal.TryParse(s.Value, out sumadd))
                        return false;
                if (sumadd > 0)
                {
                    var client = Table.SingleOrDefault(x => x.UserId == uid);
                    if (client != null)
                    {
                        BonusFinanceModel bm = new BonusFinanceModel();
                        String hosta = HttpContext.Current.Request.UserHostAddress;
                                
                        return bm.AddBonus(newClient, client, sumadd, hosta ) > 0;
                    }
                }
            }
            catch
            {
            }
            return false;
        }
		public void UpdateClient(Client newClient, Guid originalId)
		{
			var originalClient = GetClient(originalId);
			originalClient.FirstName = newClient.FirstName;
			originalClient.LastName = newClient.LastName;
			originalClient.Birthday = newClient.Birthday;
			originalClient.Sex = newClient.Sex;
			originalClient.Address = newClient.Address;
			originalClient.About = newClient.About;
			originalClient.HomeSiteUrl = newClient.HomeSiteUrl;
			originalClient.CountryId = newClient.CountryId;
            originalClient.ShowToOther = newClient.ShowToOther;
			SubmitAllChanges();
		}

		public void ChangeCulture(Client client, string culture)
		{
			var originalClient = GetClient(client.UserId);
			originalClient.Culture = culture;
			SubmitAllChanges();
		}

		public void DeleteClient(Guid id, bool forceLogout)
		{
			var client = GetClient(id);
			var clientName = client.MembershipUser.UserName;

			if (Roles.GetRolesForUser(clientName).Length > 0)
			{
				Roles.RemoveUserFromRoles(clientName, Roles.GetRolesForUser(clientName));
			}

			_financeModel.DeleteFinance(client.UserId);
			foreach (var onlineContent in client.OnlineContents)
			{
				_onlineContentModel.DeleteContent(onlineContent.Id);
			}
			_onlineRatingModel.DeleteAll(client.OnlineRatings);
			_onlineContentClaimModel.DeleteAll(client.OnlineContentClaims);
			_teamChatModel.DeleteAll(client.TeamChats);
			_waitModel.DeleteAll(client.Waits);

			Delete(client);
			Membership.DeleteUser(clientName);

			if (forceLogout)
			{
				FormsAuthentication.SignOut();
			}
		}

		public void LockUnlockClient(string login, bool isLock)
		{
			var user = Membership.GetUser(login);

			if (user != null)
			{
				user.IsApproved = !isLock;
				Membership.UpdateUser(user);
			}
		}
	}
}